#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

// #define SELF 1 // 自己定制的协议

/*  读到的请求无法保证是一个完整的，所以需要对字符串流进行分析，最后再读取
 *    协议的报头和报文的完整格式——"len"\r\n"{json}"\r\n
 *    len：有效载荷的长度-json串的长度
 *    第一个:\r\n -区分len和json串
 *    第二个:方便打印Debug
 */

/*之前使用json实现的序列化和反序列化，本次尝试手写序列化和反序列化的过程，自己定制标准如下:
 *      Request  : x oper y
 *      Response : result code
 */

static const std::string sep = "\r\n";
static const std::string pro_sep = " ";

/// @brief 添加报头
/// @param jsonstr json串
/// @return 报文的完整格式："len"\r\n"{json}"\r\n
std::string EnCode(const std::string &jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);
    return lenstr + sep + jsonstr + sep;
}

/// @brief 在网络字节流中提取出完整的报文,并删除头部已经解析的报文
/// @param pagestream
/// @return 报文的完整格式："len"\r\n"{json}"\r\n
std::string DeCode(std::string &pagestream)
{
    // 找分隔符
    auto pos = pagestream.find(sep);
    if (pos == std::string::npos)
        return std::string();
    // 解析len
    std::string lenstr = pagestream.substr(0, pos);
    size_t len = std::stoi(lenstr);
    // 检查整体长度
    size_t total = lenstr.size() + len + 2 * sep.size();
    if (pagestream.size() < total)
        return std::string();
    // 到这里，字节流中有至少一个完整报文
    std::string jsonstr = pagestream.substr(pos + sep.size(), len);
    // 删除头部
    pagestream.erase(0, total);
    return jsonstr;
}

// 客户端发送的请求
class Request
{
public:
    Request()
    {
    }

    Request(int x, int y, char oper)
        : _x(x), _y(y), _oper(oper)
    {
    }

    // 带出序列化后的串
    bool Serialize(std::string *out)
    {
#ifdef SELF // 自己定制的协议
        std::string str_x = std::to_string(_x);
        std::string str_y = std::to_string(_y);
        // 格式：x 运算符 y
        *out = str_x + pro_sep + _oper + pro_sep + str_y;
        return true;
#else
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        Json::FastWriter writer;

        // Json::StyledWriter writer;
        std::string s = writer.write(root);

        *out = s;
        return true;
#endif
    }

    // true if the document was successfully parsed, false if an error occurred.
    bool Deserialize(const std::string &in)
    {
#ifdef SELF
        //"x oper y"
        auto leftpos = in.find(pro_sep); // 从左向右，找第一个空格
        if (leftpos == std::string::npos)
            return false;
        auto rightpos = in.rfind(pro_sep); // 从右向左，找第二个空格
        if (rightpos == leftpos)           // 表示串内只有一个空格，不符合协议要求
            return false;

        // 特殊判断协议格式
        if (leftpos + pro_sep.size() + 1 != rightpos)
            return false;

        std::string left_data = in.substr(0, leftpos);
        std::string right_data = in.substr(rightpos + pro_sep.size());
        if (left_data.empty() || right_data.empty())
            return false;

        // 结构化数据
        _oper = in[rightpos - 1];
        _x = std::stoi(left_data);
        _y = std::stoi(right_data);
        return true;
#else
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if (!res)
            return false;

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();

        return true;
#endif
    }

    ~Request()
    {
    }
    int GetX()
    {
        return _x;
    }
    int GetY()
    {
        return _y;
    }
    char GetOper()
    {
        return _oper;
    }
    void SetValue(int x, int y, char oper)
    {
        _x = x;
        _y = y;
        _oper = oper;
    }

private:
    int _x;
    int _y;
    char _oper;
};

// 服务端回应的结果
class Response
{
public:
    Response() : _result(0), _code(0), _desc("Success")
    {
    }

    bool Serialize(std::string *out)
    {
#ifdef SELF
        std::string str_result = std::to_string(_result);
        std::string str_code = std::to_string(_code);
        // 格式：result code
        *out = str_result + pro_sep + str_code;
        return true;
#else
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;

        Json::FastWriter writer;
        // Json::StyledWriter writer;
        std::string s = writer.write(root);

        *out = s;
        return true;
#endif
    }
    bool Deserialize(const std::string &in)
    {
#ifdef SELF
        auto pos = in.find(pro_sep);
        if (pos == std::string::npos)
            return false;

        std::string str_relust = in.substr(0, pos);
        std::string str_code = in.substr(pos + pro_sep.size());

        if (str_code.empty() || str_relust.empty())
            return false;

        // 得到结构化的数据
        _result = std::stoi(str_relust);
        _code = std::stoi(str_code);
        _desc = std::string();
        return true;

#else
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if (!res)
            return false;

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();

        return true;
#endif
    }
    ~Response()
    {
    }
    void SetResult(int result)
    {
        _result = result;
    }
    void SetCode(int code)
    {
        _code = code;
    }
    void SetDesc(const std::string &desc)
    {
        _desc = desc;
    }
    void Print()
    {
        std::cout << "result: " << _result << "  " << "code: " << _code << "  " << "desc: " << _desc << std::endl;
        std::cout << std::endl;
    }

    std::string GetDesc()
    {
        return _desc;
    }

private:
    int _result;       // 计算的结果
    int _code;         // 状态码 0：success 1：div zero 2：非法操作
    std::string _desc; // 错误的具体描述
};
